//
// Created by wzr on 2021/5/8.
//

#include "SchoolCard.h"
#include <utility>
/*
 * Init User
 */
User::User(int id,int typ, std::string nam, std::string pos)
        : id(id), type(typ), name(std::move(nam)), position(std::move(pos))
{}

/*
 * Get the type of the card.
 * 1 == 教师卡
 * 2 == 学生卡
 * 3 == 限制卡
 */
std::string User::getType() const {
    if(type == 1){
        return "教师卡";
    }else if(type == 2){
        return "学生卡";
    }else{
        return "限制卡";
    }
}

/*
 * Get the position of the card.
 */
const string &User::getPosition() const {
    return position;
}

int User::getId() const {
    return id;
}

/*
 * Add money to the card.
 * Update to the database, the function is in data.h
 */
void Card::AddMoney(int money){
    updateBalance(num, money);
    this->balance += money;
}

/*
 * Init the Card.
 */
Card::Card(User *user, int number, int balance, int tak, int state)
:cardholder(user), num(number), balance(balance), taking(tak), state(state)
{}

void Card::ShowInfo() const{
    MOVERIGHT(100);std::cout<<"User:"           <<this->cardholder->getName()       <<std::endl;
    MOVERIGHT(100);std::cout<<"No:"             <<this->num                         <<std::endl;
    MOVERIGHT(100);std::cout<<"Card type:"      <<this->cardholder->getType()       <<std::endl;
    MOVERIGHT(100);std::cout<<"User position:"  <<this->cardholder->getPosition()   <<"       "<<std::endl;
    MOVERIGHT(100);std::cout<<"Balance:"        <<this->balance                     <<std::endl;
    MOVERIGHT(100);std::cout<<"Taking:"         <<this->taking                      <<std::endl;
    MOVERIGHT(100);std::cout<<"Taking:"         <<this->getState()                  <<std::endl;
}
void Card::TakeBus(Bus* busTaken) {
    if(!state)                                                              //Check if valid
        return;
    ShowInfo();
    if(busTaken->isFull()){                                                 //Check if the bus is full
        MOVERIGHT(100);std::cout<<"Fail to take. The bus is full.";
    }else{
        addTaking();                                                        //If not full
        ShowTakingResult(busTaken);                                         //Show the result and update free and balance
    }
}

std::string Card::getState() const {
    if(state){
        return "可使用";
    }else{
        return "已挂失，不可用";
    }
}

void Card::addTaking() {
    taking++;               //local
    incTaking(num);         //database
}


StudentCard::StudentCard(User *user, int number, int money, int taking, int state): Card(user, number, money, taking, state)
{}

void StudentCard::ShowTakingResult(Bus* busTaken){
    std::string message;
    bool success = true;
    if(2 <= balance && balance <= 5){
        balance -= 2;
        updateBalance(num, -2);
        message = "Low balance, please add money in time!";
    }else if(balance > 5){
        balance -= 2;
        updateBalance(num, -2);
        message = "Taking bus successfully!";
    }else{
        success = !success;
        message = "balance not enough!";
    }
    if(success){
        busTaken->addPerson();
    }
    MOVERIGHT(100);std::cout<<message<<"\n"<<std::endl;
}


TeacherCard::TeacherCard(User *user, int number, int money, int taking, int state): Card(user, number, money, taking, state)
{}

void TeacherCard::ShowTakingResult(Bus* busTaken){
    std::string message;
    message = "Free to take, welcome!";
    busTaken->addPerson();
    MOVERIGHT(100);std::cout<<message<<"\n"<<std::endl;
}

LimitCard::LimitCard(User *user, int number, int money,int taking, int free, int state): Card(user, number, money,taking, state)
{
    this->free = free;
}

void LimitCard::ShowTakingResult(Bus* busTaken){
    std::string message;
    bool success = true;
    if(free>0){
        updateFree(num, -1);
        free--;
        message = "Free to take";
    }else if(free==0){
        if(2 <= balance && balance <= 5){
            updateBalance(num, -2);
            balance -= 2;
            message = "Not free from this time.\nLow balance, please kejin in time!";
        }else if(balance > 5){
            updateBalance(num, -2);
            balance -= 2;
            message = "Not free from this time.\nTaking bus successfully!";
        }else{
            success = !success;
            message = "Balance not enough!";
        }
    }
    if(success){
        busTaken->addPerson();
    }
    MOVERIGHT(100);std::cout<<message<<"\n"<<std::endl;
}


